<?php

namespace addons\booking\model;

use think\Model;
use addons\booking\model\OrderCalendar;
use addons\booking\model\RoomState;
use addons\booking\model\HouseMode;
use addons\booking\model\Comment;

class House extends Model
{

    // 表名
    protected $name = 'booking_house';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = false;

    // 追加属性
    protected $append = [
        'status_text'
    ];

    public function getStatusList()
    {
        return ['up' => __('Status up'), 'down' => __('Status down')];
    }


    public function getStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
        $list = $this->getStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    public function getImagesAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['images']) ? $data['images'] : '');
        if (!$value) {
            return [];
        }
        $value = explode(',', $value);
        foreach ($value as &$item) {
            $item = cdnurl($item, true);
        }
        return $value;
    }

//    public function getNotesInAttr($value)
//    {
//        return (array)json_decode($value, true);
//    }

//    public function getTagNamesAttr($value, $data)
//    {
//        $value = $value ? $value : (isset($data['tag_names']) ? $data['tag_names'] : '');
//        if (!$value) {
//            return [];
//        }
//        return explode(',', $value);
//    }

    /**
     * 房间列表
     *
     * @param array $param
     * @return void
     */
    public static function tableList($param, $is_page = true)
    {
        $pageNum = 15;
        if (isset($param['num']) && !empty($param['num'])) {
            $pageNum = $param['num'];
        }

        $time = strtotime(date('Y-m-d'));

        $field = 't.name as type_name,';
        $field .= 'h.id,h.market_price,h.tag_config_ids,h.name,h.views,h.area,h.livenums,h.status,h.images,h.createtime,';
        $field .= 'GROUP_CONCAT(c.name ORDER BY FIND_IN_SET(c.id, h.tag_config_ids)) tag_names,';
        $field .= "if(d.price>0,d.price,h.price) as house_price";

        $where = self::getTableWhere($param);
        $order = self::getTableOrderBy($param);

        $house = self::field($field)
            ->where($where)
            ->alias('h')
            ->join('booking_config c', 'FIND_IN_SET(c.id,h.tag_config_ids)', 'LEFT')
            ->join('booking_config t', 'h.type_config_id=t.id', 'LEFT')
            ->join('booking_calendar d', 'd.house_id=h.id AND d.day_time=' . $time, 'LEFT')
            ->group('h.id')
            ->order($order);

        if ($is_page) {
            return $house->paginate($pageNum);
        } else {
            return $house->limit($pageNum)->select();
        }
    }

    /**
     * 排序出来了
     *
     * @param array $param
     * @return void
     */
    private static function getTableOrderBy($param)
    {
        $order = 'h.weigh desc';
        if (isset($param['orderby'])) {

            switch ($param['orderby']) {
                case 'comment':
                    //统计评论得分最高的，房间，排序
                    $list = Comment::field('sum(grade) as grades,source_id')
                        ->where('type', 0)
                        ->where('status', 'normal')
                        ->group('source_id')
                        ->order('grades desc')
                        ->select();

                    $source_ids = join(',', array_column($list, 'source_id'));
                    $order = new \think\db\Expression("field(h.id,$source_ids)");
                    break;
                case 'low_price':
                    $order = 'house_price asc';
                    break;
                case 'high_price':
                    $order = 'house_price desc';
                    break;
                case 'views':
                    $order = 'h.views desc';
                    break;
                case 'distance':
                    //取门店的按坐标排序，房间按门店拍讯
                    if (isset($param['latitude']) && !empty($param['latitude']) && isset($param['longitude']) && !empty($param['longitude'])) {
                        $latitude = $param['latitude'];
                        $longitude = $param['longitude'];
                        $PI = M_PI;
                        $fields = "id,latitude,longitude,(2 * 6378.137 * ASIN(SQRT(POW(SIN($PI*({$latitude}-latitude)/360),2)+COS($PI*{$latitude}/180)* COS(latitude * $PI/180)*POW(SIN($PI*({$longitude}-longitude)/360),2)))) as distance";
                        $store = \addons\booking\model\Store::field($fields)->order('distance asc')->select();
                        $store_ids = join(',', array_column($store, 'id'));
                        $order = new \think\db\Expression("field(h.store_id,$store_ids)");
                    }
                    break;
            }
        }
        return $order;
    }

    /**
     * 条件处理
     *
     * @param array $param
     * @return void
     */
    private static function getTableWhere($param)
    {
        return function ($query) use ($param) {
            $query->where('h.status', 'up');
            //门店id
            if (isset($param['store_id']) && !empty($param['store_id'])) {
                $query->where('h.store_id', $param['store_id']);
            }
            //门店ids
            if (isset($param['store_ids']) && !empty($param['store_ids'])) {
                $query->where('h.store_id', 'in', $param['store_ids']);
            }
            //门店ids
            if (isset($param['keyword']) && !empty($param['keyword'])) {
                $query->where('h.name|h.intro', 'like', '%' . $param['keyword'] . '%');
            }
            //按日期筛选房间【排除被预订的】
            if (isset($param['calendar']) && !empty($param['calendar'])) {
                $calendar = explode('/', $param['calendar']);
                $time1 = strtotime($calendar[0]);
                $time2 = $time1 + 3600 * 24;
                if (count($calendar) == 2) { //时间范围
                    $time2 = strtotime($calendar[1]);
                }
                $data = OrderCalendar::field('house_id')->where('status', 'normal')->where('reserve_time', '>=', $time1)->where('reserve_time', '<', $time2)->group('house_id')->select();
                $house_ids = [];
                foreach ($data as $item) {
                    $house_ids[$item['house_id']] = $item['house_id'];
                }
                $query->where('h.id', 'not in', $house_ids);
            }
            //房间ids
            if (isset($param['house_ids']) && !empty($param['house_ids'])) {
                $query->where('h.id', 'in', $param['house_ids']);
            }
            //房型
            if (isset($param['house']) && !empty($param['house'])) {
                if (isset($param['multiple']) && $param['multiple']) { //多选
                    $query->where('h.type_config_id', 'in', $param['house']);
                } else {
                    $query->where('h.type_config_id', $param['house']);
                }
            }
            //标签
            if (isset($param['tag']) && !empty($param['tag'])) {
                if (isset($param['multiple']) && $param['multiple']) { //多选
                    $tagArr = explode(',', $param['tag']);
                    $sql = '1=1';
                    foreach ($tagArr as $id) {
                        $id = (int)$id;
                        $sql .= " AND FIND_IN_SET($id,h.tag_config_ids)";
                    }
                    $query->where($sql);
                } else {
                    $query->where("FIND_IN_SET(" . intval($param['tag']) . ",h.tag_config_ids)");
                }
            }
            //楼层
            if (isset($param['floor']) && !empty($param['floor'])) {
                if (isset($param['multiple']) && $param['multiple']) { //多选
                    $query->where('h.floor_config_id', 'in', $param['floor']);
                } else {
                    $query->where('h.floor_config_id', $param['floor']);
                }
            }
            //配套设施
            if (isset($param['facility']) && !empty($param['facility'])) {
                if (isset($param['multiple']) && $param['multiple']) { //多选
                    $facilityArr = explode(',', $param['facility']);
                    $sql = '1=1';
                    foreach ($facilityArr as $id) {
                        $id = (int)$id;
                        $sql .= " AND FIND_IN_SET($id,h.facility_config_ids)";
                    }
                    $query->where($sql);
                } else {
                    $query->where("FIND_IN_SET(" . intval($param['facility']) . ",h.facility_config_ids)");
                }
            }
            //价格区间
            if (isset($param['price']) && !empty($param['price'])) {
                $array = explode('-', $param['price']);
                if (count($array) == 2) {
                    $query->where('h.price|d.price', 'between', $array);
                }
            }
            //可住人数区间
            if (isset($param['nums']) && !empty($param['nums'])) {
                $array = explode('-', $param['nums']);
                if (count($array) == 2) {
                    $query->where('h.livenums', 'between', $array);
                }
            }
        };
    }

    /**
     * 房间详情
     *
     * @param int $id
     * @return Object
     */
    public static function getDetail($id)
    {
        $data = self::with([
            //日历价格
            'Calendar'      => function ($query) {
                $query->field('id,house_id,day_time,price')->where('day_time', '>', strtotime(date('Y-m-d' . '00:00:00', time() - 3600 * 24)))->order('day_time asc'); //还有小于的月份
            },
            //被预订日期
            'OrderCalendar' => function ($query) {
                $query->field('id,house_id,reserve_time')->where('status', 'normal')->where('reserve_time', '>', strtotime(date('Y-m-d' . '00:00:00', time() - 3600 * 24)))->order('reserve_time desc');
            },
            //门店
            'Store'         => function ($query) {
                $query->field('id,name,latitude,longitude,address');
            },
            'Type'          => function ($query) {
                $query->field('id,name');
            }
        ])->field('h.id,h.store_id,h.type_config_id,h.floor_config_id,h.tag_config_ids,h.facility_config_ids,h.market_price,h.price,h.to_shop_pay,h.name,h.checkin_time,h.checkout_time,h.notes_in,h.views,h.images,h.content,h.intro,h.area,h.livenums,h.createtime,h.status')
            ->alias('h')
            ->where('h.id', $id)->where('h.status', 'up')->find();
        if ($data) {
            $groupName = ['facility' => [], 'tag' => []];
            $tagConfigIds = explode(',', $data['tag_config_ids']);
            $facilityConfigIds = explode(',', $data['facility_config_ids']);
            $configIds = array_merge($tagConfigIds, $facilityConfigIds);
            $configIds = array_filter($configIds);
            if ($configIds) {
                $configData = Config::where('id', 'in', $configIds)->orderRaw("FIELD(`id`, " . implode(',', $configIds) . ")")->column('id,name');
                foreach ($tagConfigIds as $index => $tagConfigId) {
                    if (isset($configData[$tagConfigId])) {
                        $groupName['tag'][] = $configData[$tagConfigId];
                    }
                }
                foreach ($facilityConfigIds as $index => $facilityConfigId) {
                    if (isset($configData[$facilityConfigId])) {
                        $groupName['facility'][] = $configData[$facilityConfigId];
                    }
                }
            }
            $data['group_names'] = $groupName;
        }

        return $data;
    }

    //获取所有的房间
    public static function get_all_house($store_id = 0,$date='',$where=[])
    {
        if(!$date) return [];
        $field = 'h.id,h.store_id,h.room,h.price,h.floor_config_id,type_config_id,m.name as type_name';
        $where['h.store_id'] = $store_id;
        $where['h.status'] = 'up';
        $list =  self::with([
            'RoomState' => function ($query)use($date,$store_id) {
                $query->where('store_id',$store_id)->where('date',$date)->field('id,house_id,status,is_lock,lock_reason,lock_time');
            },
        ]) ->alias('h')
        ->join('house_mode m','m.id = h.type_config_id','left')
        ->where($where)
        ->field($field)->select();

        $list =  collection($list)->toArray();

        foreach ($list as $k=>$v){
            if(empty($v['room_state'])){
                $room_state = [];
                $room_state = [
                    'id' => '',
                    'house_id' => $v['id'],
                    'status' => "0",
                    'is_lock' => '0',
                    'lock_reason' => '',
                    'lock_time' => 0
                ];
                $list[$k]['room_state'] = $room_state;
            }
        }

        return $list ? $list : [];
    }

    //日历价格
    public function Calendar()
    {
        return $this->hasMany('Calendar', 'house_id', 'id');
    }

    //已预订日历(订单日历)
    public function OrderCalendar()
    {
        return $this->hasMany('OrderCalendar', 'house_id', 'id');
    }

    //门店
    public function Store()
    {
        return $this->belongsTo('Store', 'store_id', 'id', [], 'LEFT');
    }

    //类型
    public function Type()
    {
        return $this->belongsTo('Config', 'type_config_id', 'id', [], 'LEFT');
    }

    //房态
    public function RoomState()
    {
        return $this->hasOne('RoomState', 'house_id', 'id');
    }
}
